package com.bicon.botu.core.base.config;

import com.alibaba.fastjson.JSONObject;
import com.bicon.botu.core.base.common.entity.HttpLogEntity;
import com.bicon.botu.core.base.common.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Http请求日志记录
 *
 * @author tandk
 * @date 2017/6/12 0012 下午 4:28
 */
@Slf4j
@Aspect
@Component
public class HttpLogAspect {

    @Value("${spring.application.name}")
    String appName;

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * *..api.*Api*.*(..))" +
            " || execution(public * *..controller.*Controller*.*(..))" +
            " || execution(public * *..rpc.*Rpc*.*(..))" +
            " || execution(public * com.bicon.botu.core.base.config.GlobalExceptionHandler.*(..))")
    public void httpLog() {
    }

    @Before("httpLog()")
    public void doBefore() throws Throwable {
        startTime.set(System.currentTimeMillis());
    }

    @AfterReturning(returning = "ret", pointcut = "httpLog()")
    public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        long endTime = System.currentTimeMillis();

        HttpLogEntity httpLogEntity = new HttpLogEntity();
        httpLogEntity.setUrl(request.getRequestURL().toString());
        httpLogEntity.setParamMap(HttpUtil.getParamMap(request));
        httpLogEntity.setHttpMethod(request.getMethod());
        httpLogEntity.setIp(HttpUtil.getRemoteHost(request));
        httpLogEntity.setClazz(joinPoint.getSignature().getDeclaringTypeName());
        httpLogEntity.setMethod(joinPoint.getSignature().getName());
        httpLogEntity.setReturnResult(ret);
        httpLogEntity.setStartTime(startTime.get());
        httpLogEntity.setEndTime(endTime);
        httpLogEntity.setHttpTime(endTime - httpLogEntity.getStartTime());
        String resultJson;
        try {
            resultJson = JSONObject.toJSONString(httpLogEntity);
        } catch (Exception e) {
            httpLogEntity.setReturnResult("return data parse json exception");
            resultJson = JSONObject.toJSONString(httpLogEntity);
        }
        startTime.remove();
        log.info("【{}_{}_{}_End】{}", httpLogEntity.getIp(), HttpUtil.getSourceType(request), httpLogEntity.getHttpMethod(), resultJson);
    }
}